home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP02.ZIP / CHAP02 / SCHMOO / POLYLINE.CPP < prev    next >
C/C++ Source or Header  |  1993-06-16  |  25KB  |  1,152 lines

  1. /*
  2.  * POLYLINE.CPP
  3.  *
  4.  * Implementation of the CPolyline class.
  5.  *
  6.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  7.  *
  8.  * Kraig Brockschmidt, Software Design Engineer
  9.  * Microsoft Systems Developer Relations
  10.  *
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16.  
  17. #include "schmoo.h"
  18.  
  19.  
  20.  
  21. /*
  22.  * CPolyline:CPolyline
  23.  * CPolyline::~CPolyline
  24.  *
  25.  * Constructor Parameters:
  26.  *  hInst           HINSTANCE of the application we're in.
  27.  */
  28.  
  29. CPolyline::CPolyline(HINSTANCE hInst)
  30.     : CWindow(hInst)
  31.     {
  32.     m_pAdv=NULL;
  33.     m_hWnd=NULL;
  34.     return;
  35.     }
  36.  
  37.  
  38. CPolyline::~CPolyline(void)
  39.     {
  40.     //No need to destroy our window since we're a child
  41.     return;
  42.     }
  43.  
  44.  
  45.  
  46.  
  47.  
  48. /*
  49.  * CPolyline::FInit
  50.  *
  51.  * Purpose:
  52.  *  Instantiates a polyline window within a given parent.  The
  53.  *  parent may be a main application window, could be an MDI child
  54.  *  window. We really do not care.
  55.  *
  56.  * Parameters:
  57.  *  hWndParent      HWND of the parent of this window
  58.  *  pRect           LPRECT that this window should occupy
  59.  *  dwStyle         DWORD containing the window's style flags
  60.  *  uID             UINT ID to associate with this window
  61.  *  pAdv            LPCPolylineAdviseSink of the sink wanting our notifications.
  62.  *
  63.  * Return Value:
  64.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  65.  */
  66.  
  67. BOOL CPolyline::FInit(HWND hWndParent, LPRECT pRect, DWORD dwStyle, UINT uID
  68.     , LPCPolylineAdviseSink pAdv)
  69.     {
  70.     m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY, SZCLASSPOLYLINE
  71.         , SZCLASSPOLYLINE, dwStyle, pRect->left, pRect->top
  72.         , pRect->right-pRect->left, pRect->bottom-pRect->top
  73.         , hWndParent, (HMENU)uID, m_hInst, (LPVOID)this);
  74.  
  75.     if (NULL!=m_hWnd)
  76.         m_pAdv=pAdv;
  77.  
  78.     return (NULL!=m_hWnd);
  79.     }
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87. /*
  88.  * CPolyline::New
  89.  *
  90.  * Purpose:
  91.  *  Cleans out and reinitializes the data to defaults.
  92.  *
  93.  * Parameters:
  94.  *  None
  95.  *
  96.  * Return Value:
  97.  *  None
  98.  */
  99.  
  100. void CPolyline::New(void)
  101.     {
  102.     UINT        i;
  103.  
  104.     m_pl.wVerMaj=VERSIONMAJOR;
  105.     m_pl.wVerMin=VERSIONMINOR;
  106.  
  107.     //Our rectangle is the size of our window's client area.
  108.     GetClientRect(m_hWnd, &m_pl.rc);
  109.  
  110.     //Clean out the POLYLINE structure and repaint the window.
  111.     for (i=0; i< CPOLYLINEPOINTS; i++)
  112.         {
  113.         m_pl.rgpt[i].x=0;
  114.         m_pl.rgpt[i].y=0;
  115.         }
  116.  
  117.     m_pl.cPoints      =0;
  118.     m_pl.rgbBackground=GetSysColor(COLOR_WINDOW);
  119.     m_pl.rgbLine      =GetSysColor(COLOR_WINDOWTEXT);
  120.     m_pl.iLineStyle   =PS_SOLID;
  121.  
  122.     InvalidateRect(m_hWnd, NULL, TRUE);
  123.     UpdateWindow(m_hWnd);
  124.  
  125.     //Inform the advise sink of this data change.
  126.     if (NULL!=m_pAdv)
  127.         m_pAdv->OnDataChange();
  128.  
  129.     return;
  130.     }
  131.  
  132.  
  133.  
  134.  
  135. /*
  136.  * CPolyline::Undo
  137.  *
  138.  * Purpose:
  139.  *  Reverses previous actions in a Polyline.
  140.  *
  141.  * Parameters:
  142.  *  None
  143.  *
  144.  * Return Value:
  145.  *  BOOL            TRUE if we can Undo more, FALSE otherwise.
  146.  */
  147.  
  148. BOOL CPolyline::Undo(void)
  149.     {
  150.     //Decrement the number of active points and repaint.
  151.     if (m_pl.cPoints > 0)
  152.         {
  153.         m_pl.cPoints--;
  154.         InvalidateRect(m_hWnd, NULL, TRUE);
  155.         UpdateWindow(m_hWnd);
  156.         }
  157.  
  158.     if (NULL!=m_pAdv)
  159.         m_pAdv->OnPointChange();
  160.  
  161.     //Return if we can undo any more.
  162.     return (0!=m_pl.cPoints);
  163.     }
  164.  
  165.  
  166.  
  167.  
  168.  
  169. /*
  170.  * CPolyline::ReadFromFile
  171.  *
  172.  * Purpose:
  173.  *  Loads our data (any known version) from a file handle returning
  174.  *  the version number of the data or an error value.
  175.  *
  176.  * Parameters:
  177.  *  pszFile         LPSTR of the file to open.
  178.  *
  179.  * Return Value:
  180.  *  LONG            Version number or negative POLYLINE_E_* value.
  181.  */
  182.  
  183. LONG CPolyline::ReadFromFile(LPSTR pszFile)
  184.     {
  185.     OFSTRUCT        of;
  186.     HFILE           hFile;
  187.     POLYLINEDATA    pl;
  188.     UINT            cb=-1;
  189.     UINT            cbExpect=0;
  190.  
  191.     if (NULL==pszFile)
  192.         return POLYLINE_E_READFAILURE;
  193.  
  194.     hFile=OpenFile(pszFile, &of, OF_READ);
  195.  
  196.     if (HFILE_ERROR==hFile)
  197.         return POLYLINE_E_READFAILURE;
  198.  
  199.     //Read version numbers and seek back to file beginning.
  200.     cb=_lread(hFile, (LPSTR)&pl, 2*sizeof(WORD));
  201.  
  202.     if (2*sizeof(WORD)!=cb)
  203.         {
  204.         _lclose(hFile);
  205.         return POLYLINE_E_READFAILURE;
  206.         }
  207.  
  208.     _llseek(hFile, 0L, 0);
  209.  
  210.     /*
  211.      * For version 2.0, read the entire file.  For version 1.0 read
  212.      * the file up to CBPOLYLINEDATAVER10.  For anything else, give an
  213.      * error.
  214.      */
  215.  
  216.     switch (pl.wVerMaj)
  217.         {
  218.         case VERSIONMAJOR:  //2.x
  219.             switch (pl.wVerMin)
  220.                 {
  221.                 case VERSIONMINOR:  //2.0
  222.                     cbExpect=CBPOLYLINEDATA;
  223.                     break;
  224.  
  225.                 default:
  226.                     break;
  227.                 }
  228.             break;
  229.  
  230.         case 1: //1.x
  231.             switch (pl.wVerMin)
  232.                 {
  233.                 case 0:  //1.0
  234.                     cbExpect=CBPOLYLINEDATA10;
  235.                     break;
  236.  
  237.                 default:
  238.                     break;
  239.                 }
  240.             break;
  241.  
  242.         default:
  243.             break;
  244.         }
  245.  
  246.     if (0==cbExpect)
  247.         {
  248.         _lclose(hFile);
  249.         return POLYLINE_E_UNSUPPORTEDVERSION;
  250.         }
  251.  
  252.     cb=_lread(hFile, (LPSTR)&pl, cbExpect);
  253.     _lclose(hFile);
  254.  
  255.     if (cbExpect!=cb)
  256.         return POLYLINE_E_READFAILURE;
  257.  
  258.     /*
  259.      * If we loaded successfully, make the data current.  By using DataSet
  260.      * we centralize our version upgrading.  We size the polyline window
  261.      * to the data AND notify the document so it sizes to the polyline.
  262.      */
  263.     DataSet(&pl, TRUE, TRUE);
  264.  
  265.     //Return what version we just loaded.
  266.     return MAKELONG(pl.wVerMin, pl.wVerMaj);
  267.     }
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274. /*
  275.  * CPolyline::WriteToFile
  276.  *
  277.  * Purpose:
  278.  *  Ignorantly writes our current data into an opened file in a particular
  279.  *  version.
  280.  *
  281.  * Parameters:
  282.  *  pszFile         LPSTR filename in which to store the data.
  283.  *  lVer            LONG providing version number Major (HI) and Minor (Low)
  284.  *
  285.  * Return Value:
  286.  *  LONG            A POLYLINE_E_* value.
  287.  */
  288.  
  289. LONG CPolyline::WriteToFile(LPSTR pszFile, LONG lVer)
  290.     {
  291.     UINT            cb;
  292.     UINT            cbExpect=0;
  293.     WORD            wVerMaj=HIWORD(lVer);
  294.     WORD            wVerMin=LOWORD(lVer);
  295.     POLYLINEDATA    pl;
  296.     HFILE           hFile;
  297.     OFSTRUCT        of;
  298.  
  299.     if (NULL==pszFile)
  300.         return POLYLINE_E_READFAILURE;
  301.  
  302.     //Get a copy of our data in the version we're going to save.
  303.     DataGet(&pl, lVer);
  304.  
  305.     switch (wVerMaj)
  306.         {
  307.         case VERSIONMAJOR:  //2.x
  308.             switch (wVerMin)
  309.                 {
  310.                 case VERSIONMINOR:  //2.0
  311.                     cbExpect=CBPOLYLINEDATA;
  312.                     break;
  313.  
  314.                 default:
  315.                     break;
  316.                 }
  317.             break;
  318.  
  319.         case 1: //1.x
  320.             switch (wVerMin)
  321.                 {
  322.                 case 0:  //1.0
  323.                     cbExpect=CBPOLYLINEDATA10;
  324.                     break;
  325.  
  326.                 default:
  327.                     break;
  328.                 }
  329.             break;
  330.  
  331.         default:
  332.             break;
  333.         }
  334.  
  335.     if (0==cbExpect)
  336.         return POLYLINE_E_UNSUPPORTEDVERSION;
  337.  
  338.     hFile=OpenFile(pszFile, &of, OF_CREATE | OF_WRITE);
  339.  
  340.     if (HFILE_ERROR==hFile)
  341.         return DOCERR_COULDNOTOPEN;
  342.  
  343.     cb=_lwrite(hFile, (LPSTR)&pl, cbExpect);
  344.     _lclose(hFile);
  345.  
  346.     return (cbExpect==cb) ? POLYLINE_E_NONE : POLYLINE_E_WRITEFAILURE;
  347.     }
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357. /*
  358.  * CPolyline::DataSet
  359.  *
  360.  * Purpose:
  361.  *  Sets the current data in this Polyline to a given structure.
  362.  *
  363.  * Parameters:
  364.  *  ppl             LPPOLYLINEDATA to initialize to.
  365.  *  fSizeToData     BOOL indicating if we're to size to the data or scale it.
  366.  *  fNotify         BOOL indicating if we're to send an advise on this change.
  367.  *
  368.  * Return Value:
  369.  *  LONG            A POLYLINE_E_* value.
  370.  */
  371.  
  372. LONG CPolyline::DataSet(LPPOLYLINEDATA ppl, BOOL fSizeToData,